Micron Document
πŸŽ–οΈGitΠ―Ρ€Π°πŸŽ–οΈ

Node / meshtastic / Meshtastic-Android / files / docs / en / developer / architecture.md

Displaying Raw β€’ View rendered β€’ Download

docs/en/developer/architecture.md fix/qr-error-correction (7b45f84f) Text, 7.82 KB

---
title: Architecture
parent: Developer Guide
nav_order: 1
last_updated: 2026-06-11
aliases:
Tff7b72- layers
Tff7b72- module-architecture
Tff7b72- kmp
Tc9d1d9 - radio-control
Tc9d1d9---

Tc9d1d9# Architecture

The Meshtastic Android and Desktop apps follow a modular Kotlin Multiplatform (KMP) architecture with clear layer boundaries (iOS is currently a compile-only validation target β€” there is no shipping iOS app yet).

Tc9d1d9## Layer Overview

Ta5d6ff```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ androidApp / desktopApp β”‚ Platform entry points
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ feature/* modules β”‚ UI + Business Logic
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ core/* modules β”‚ Shared infrastructure
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Platform (Android/JVM/iOS) β”‚ OS-specific bindings
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

Tc9d1d9## Module Categories

Tc9d1d9### `androidApp/` β€” Android Application

The Android application entry point:
Tff7b72- Activity, Application, and Manifest definitions
Tff7b72- Koin DI module composition (Ta5d6ff`AppKoinModule`)
Tff7b72- Flavor-specific bindings (Ta5d6ff`google/`, Ta5d6ff`fdroid/`)
Tff7b72- Android-only integrations (widgets, services)

Tc9d1d9### `desktopApp/` β€” Desktop JVM Application

The Desktop (Linux/macOS/Windows) entry point:
Tff7b72- Compose Desktop window management
Tff7b72- Desktop-specific DI (Ta5d6ff`DesktopKoinModule`)
Tff7b72- Platform stubs for Android-only capabilities
Tff7b72- BLE (Kable), Serial, and TCP transport implementations

Tc9d1d9### `feature/*` β€” Feature Modules

Each Ta5d6ff`feature/` module owns a vertical slice of functionality:

| Module | Responsibility |
|--------|---------------|
| Ta5d6ff`feature:intro` | Onboarding/welcome flow |
| Ta5d6ff`feature:messaging` | Messages, channels, contacts, quick chat |
| Ta5d6ff`feature:connections` | Bluetooth/USB/TCP connection management |
| Ta5d6ff`feature:map` | Map display, waypoints |
| Ta5d6ff`feature:node` | Node list, node detail, metrics |
| Ta5d6ff`feature:settings` | All configuration screens |
| Ta5d6ff`feature:firmware` | Firmware update flow |
| Ta5d6ff`feature:docs` | In-app documentation browser |
| Ta5d6ff`feature:wifi-provision` | WiFi provisioning |
| Ta5d6ff`feature:widget` | Android home screen widgets |
| Ta5d6ff`feature:discovery` | Mesh network discovery |
| Ta5d6ff`feature:car` | Android Auto / Car App Library β€” google flavor only, conditionally registered in the google Ta5d6ff`FlavorModule` |

Feature modules:
Tff7b72- Use the Ta5d6ff`meshtastic.kmp.feature` convention plugin
Tff7b72- Depend on Ta5d6ff`core` modules, never on other Ta5d6ff`feature` modules
Tff7b72- Own their navigation entries and DI registrations
Tff7b72- Contain platform-specific implementations in Ta5d6ff`androidMain`/Ta5d6ff`jvmMain`/Ta5d6ff`iosMain`

Tc9d1d9### `core/*` β€” Core Modules

Shared infrastructure used by all features:

| Module | Responsibility |
|--------|---------------|
| Ta5d6ff`core:common` | Utilities, extensions, build config |
| Ta5d6ff`core:navigation` | Routes, deep links, Navigation 3 |
| Ta5d6ff`core:ui` | Shared Compose components, icons, theme |
| Ta5d6ff`core:resources` | Shared string resources |
| Ta5d6ff`core:model` | Domain models |
| Ta5d6ff`core:data` | Data layer abstractions |
| Ta5d6ff`core:domain` | Use cases / business logic |
| Ta5d6ff`core:database` | Room KMP database |
| Ta5d6ff`core:datastore` | DataStore preferences |
| Ta5d6ff`core:prefs` | App preferences |
| Ta5d6ff`core:repository` | Repository interfaces |
| Ta5d6ff`core:service` | Mesh service layer |
| Ta5d6ff`core:di` | DI utilities |
| Ta5d6ff`core:network` | HTTP/serial/transport |
| Ta5d6ff`core:ble` | Bluetooth LE abstractions |
| Ta5d6ff`core:barcode` | QR / barcode scanning (channel-share QR codes) |
| Ta5d6ff`core:nfc` | NFC read/write support |
| Ta5d6ff`core:takserver` | Embedded TAK server integration |
| Ta5d6ff`core:testing` | Test utilities |
| Ta5d6ff`core:konsist` | Konsist architecture/convention tests |

Protobuf models are no longer a local module β€” they come from the external Ta5d6ff`org.meshtastic:protobufs` Maven artifact (pinned in Ta5d6ff`gradle/libs.versions.toml`).

Tc9d1d9## KMP Source Sets

Each module uses the standard KMP source set hierarchy:

Ta5d6ff```
src/
β”œβ”€β”€ commonMain/ ← Shared code (all platforms)
β”œβ”€β”€ commonTest/ ← Shared tests
β”œβ”€β”€ androidMain/ ← Android-specific
β”œβ”€β”€ jvmMain/ ← Desktop JVM-specific
β”œβ”€β”€ iosMain/ ← iOS-specific
└── jvmTest/ ← Desktop test host
```

**Golden Rules:**
Tff7b72- No Ta5d6ff`android.*` imports in Ta5d6ff`commonMain`
Tff7b72- Platform-specific code goes in appropriate source set
Tff7b72- Prefer interfaces + DI over Ta5d6ff`expect`/Ta5d6ff`actual` for complex behaviors
Tff7b72- Use Ta5d6ff`expect`/Ta5d6ff`actual` only for simple declarations

Tc9d1d9## Dependency Injection

The project uses **Koin** with annotation processing:
Tff7b72- Ta5d6ff`@Module`, Ta5d6ff`@Single`, Ta5d6ff`@Factory` annotations
Tff7b72- Ta5d6ff`@ComponentScan` for automatic registration
Tff7b72- Feature modules export their own Ta5d6ff`Feature*Module` class
Tff7b72- App/Desktop compose all modules in their root DI configuration

Tc9d1d9## Radio Control

Features issue radio commands through Ta5d6ff`RadioController` (Ta5d6ff`core:repository`), a composite of four
focused sub-interfaces so callers can depend on just the slice they need:

| Sub-interface | Responsibility |
|---------------|---------------|
| Ta5d6ff`AdminController` | Config, channels, owner, device lifecycle, Ta5d6ff`editSettings { }` transactions |
| Ta5d6ff`MessagingController` | Send packets, reactions, shared contacts |
| Ta5d6ff`NodeController` | Favorite, ignore, mute, remove nodes |
| Ta5d6ff`QueryController` | Telemetry, traceroute, position/user-info queries |

Ta5d6ff`RadioControllerImpl` (Ta5d6ff`core:service`) is the in-process composition root for all targets
(Desktop, iOS, single-process Android). It assembles the four sub-controllers via Kotlin interface
delegation and adds the cross-cutting concerns (connection state, packet-id, location,
device-address switching). Commands are direct suspend calls; admin writes are fire-and-forget
because the device is the source of truth (local persistence is an optimistic cache). The layered
shape mirrors the [Tff7b72meshtastic-sdk](Te6edf3https://github.com/meshtastic/meshtastic-sdk)
Ta5d6ff`AdminApi`/Ta5d6ff`TelemetryApi` design to ease a future SDK migration.

Tc9d1d9## Service Repository

Ta5d6ff`ServiceRepository` is the reactive bridge between the mesh service and all feature/UI layers.
It is decomposed into focused provider interfaces following the Interface Segregation Principle:

| Interface | Responsibility |
|-----------|---------------|
| Ta5d6ff`ConnectionStateProvider` | Read-only Ta5d6ff`connectionState: StateFlow<ConnectionState>` |
| Ta5d6ff`TracerouteResponseProvider` | Traceroute response state + clear |
| Ta5d6ff`NeighborInfoResponseProvider` | Neighbor info response state + clear |
| Ta5d6ff`ServiceStateWriter` | Write-side for handlers (set*, emit*, clear*) |

Ta5d6ff`ServiceRepository` extends all four interfaces β€” consumers inject the narrowest interface
they actually need. For example, Ta5d6ff`ContactsViewModel` injects only Ta5d6ff`ConnectionStateProvider`
rather than the entire Ta5d6ff`ServiceRepository`, preventing accidental access to write operations
from UI code. Ta5d6ff`RadioController` also extends Ta5d6ff`ConnectionStateProvider` so VMs that already
inject a controller sub-interface can read connection state without a separate dependency.

Tc9d1d9## Navigation

Navigation uses **Navigation 3** with typed routes:
Tff7b72- All routes defined in Ta5d6ff`core/navigation/Routes.kt`
Tff7b72- Routes are Ta5d6ff`@Serializable` data classes/objects
Tff7b72- Deep links resolved through Ta5d6ff`DeepLinkRouter`
Tff7b72- Each feature registers its own navigation entries

See [Tff7b72Navigation & Deep Links](Te6edf3navigation-and-deep-links) for details.

---

Served by rngit 1.5.0 - Generated in 0.13s